# Python 2.6.4
# Project Euler, Problem 96
# Copyright 2010 Talha Zaman

import copy

def getGrid():
    f = open("sudoku.txt")
    count = 0
    while count < 50:
        count += 1
        f.readline()
        grid = [[int(c) for c in f.readline().strip()] for i in range(9)]
        yield grid

class Sudoku:
    def __init__(self):
        self.grid = [[[1 for i in range(9)] for j in range(9)] for k in range(9)]
        self.unknown = 81
        self.sGrid = []
        self.sGuess = []
        self.sUnknown = []

    def __str__(self):
        string = ""
        for i in range(9):
            for j in range(9):
                if j==3 or j==6: string += "|"
                if 10 in self.grid[i][j]: string += str(self.grid[i][j].index(10)+1)
                else: string += "X"
            if i==2 or i==5: string += "\n---+---+---"
            string += "\n"
        return string

    def load(self, ingrid):
        for i in range(9):
            for j in range(9):
                if ingrid[i][j]!=0:
                    self.insert(i, j, ingrid[i][j]-1)

    def check(self, row, col, number):
        if sum(s.grid[row][i][number] for i in range(9))>9: return False
        if sum(s.grid[i][col][number] for i in range(9))>9: return False
        if sum(s.grid[row-row%3+i][col-col%3+j][number] \
               for i in range(3) for j in range(3))>9: return False
        return True

    def insert(self, row, col, number):
        if not self.check(row, col, number): return False
        for i in range(9): self.grid[row][i][number] = 0
        for i in range(9): self.grid[i][col][number] = 0
        for i in range(row-row%3, row-row%3+3):
            for j in range(col-col%3, col-col%3+3):
                self.grid[i][j][number] = 0
        for i in range(9): self.grid[row][col][i] = 0
        self.grid[row][col][number] = 10
        self.unknown -= 1
        return True

    def scan(self):
        for i in range(9):
            for j in range(9):
                if sum(self.grid[i][j])==1:
                    return i, j, self.grid[i][j].index(1)
        return False

    def single(self):
        for num in range(9):
            for unit in range(9):
                if sum(self.grid[unit][i][num] for i in range(9))==1:
                    for scan in range(9):
                        if self.grid[unit][scan][num]==1:
                            return unit, scan, num
                if sum(self.grid[i][unit][num] for i in range(9))==1:
                    for scan in range(9):
                        if self.grid[scan][unit][num]==1:
                            return scan, unit, num
                boxRow, boxCol = 3*(unit/3), 3*(unit%3)
                if sum(self.grid[boxRow+i][boxCol+j][num] \
                   for i in range(3) for j in range(3))==1:
                    for sr in range(3):
                        for sc in range(3):
                            if self.grid[boxRow+sr][boxCol+sc][num]==1:
                                return boxRow+sr, boxCol+sc, num
        return False

    def solve(self):
        while self.unknown>0:
            new = self.scan()
            if new:
                if not self.insert(new[0], new[1], new[2]): self.badguess()
                continue
            new = self.single()
            if new:
                if not self.insert(new[0], new[1], new[2]): self.badguess()
                continue
            new = self.guess()
            if new: self.insert(new[0], new[1], new[2])
            else: self.badguess()

    def guess(self):
        best = min(sum(self.grid[i][j]) for i in range(9) for j in range(9))
        if best==0: return False
        for i in range(9):
            for j in range(9):
                if sum(self.grid[i][j])==best:
                    candidate = self.grid[i][j].index(1)
                    self.sGrid.append(copy.deepcopy(self.grid))
                    self.sGuess.append((i, j, candidate))
                    self.sUnknown.append(self.unknown)
                    return i, j, candidate
        return False

    def badguess(self):
        self.grid = self.sGrid.pop()
        self.unknown = self.sUnknown.pop()
        bad = self.sGuess.pop()
        self.grid[bad[0]][bad[1]][bad[2]] = 0

    def topleft(self):
        return 100*(self.grid[0][0].index(10)+1) + \
               10 *(self.grid[0][1].index(10)+1) + \
               1  *(self.grid[0][2].index(10)+1)

g = getGrid()
total = 0
for grid in g:
    s = Sudoku()
    s.load(grid)
    s.solve()
    total += s.topleft()
print total
